package com.maodou.core.navigation

import androidx.activity.compose.BackHandler
import androidx.compose.animation.ContentTransform
import androidx.compose.animation.core.tween
import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.ui.Modifier
import androidx.navigation3.runtime.NavEntry
import androidx.navigation3.ui.NavDisplay

// 推进栈：新页面自右向左进入，旧页面向左退出（水平切换）
private val pushSlideTransition: AnimatedContentTransitionScope<*>.() -> ContentTransform = {
    ContentTransform(
        targetContentEnter = slideIntoContainer(
            towards = AnimatedContentTransitionScope.SlideDirection.Left,
            animationSpec = tween(300)
        ),
        initialContentExit = slideOutOfContainer(
            towards = AnimatedContentTransitionScope.SlideDirection.Left,
            animationSpec = tween(300)
        )
    )
}

// 出栈返回：新页面自左向右进入，旧页面向右退出（与推进相反方向）
private val popSlideTransition: AnimatedContentTransitionScope<*>.() -> ContentTransform = {
    ContentTransform(
        targetContentEnter = slideIntoContainer(
            towards = AnimatedContentTransitionScope.SlideDirection.Right,
            animationSpec = tween(300)
        ),
        initialContentExit = slideOutOfContainer(
            towards = AnimatedContentTransitionScope.SlideDirection.Right,
            animationSpec = tween(300)
        )
    )
}

// 淡入淡出动画：适用于启动页等场景，像遮罩层消失一样
val fadeTransition: AnimatedContentTransitionScope<*>.() -> ContentTransform = {
    ContentTransform(
        targetContentEnter = fadeIn(
            animationSpec = tween(400)
        ),
        initialContentExit = fadeOut(
            animationSpec = tween(400)
        )
    )
}

// 缩放动画：新页面从中心缩放进入，旧页面缩放退出
val scaleTransition: AnimatedContentTransitionScope<*>.() -> ContentTransform = {
    ContentTransform(
        targetContentEnter = scaleIn(
            initialScale = 0.8f,
            animationSpec = tween(300)
        ) + fadeIn(animationSpec = tween(300)),
        initialContentExit = scaleOut(
            targetScale = 1.1f,
            animationSpec = tween(300)
        ) + fadeOut(animationSpec = tween(300))
    )
}

// 无动画：直接切换
val noneTransition: AnimatedContentTransitionScope<*>.() -> ContentTransform = {
    ContentTransform(
        targetContentEnter = fadeIn(animationSpec = tween(0)),
        initialContentExit = fadeOut(animationSpec = tween(0))
    )
}

/**
 * 根据动画类型获取对应的转场动画
 */
fun getTransitionByType(animationType: NavigationAnimation, isForward: Boolean = true): AnimatedContentTransitionScope<*>.() -> ContentTransform {
    return when (animationType) {
        NavigationAnimation.SLIDE -> if (isForward) pushSlideTransition else popSlideTransition
        NavigationAnimation.FADE -> fadeTransition
        NavigationAnimation.SCALE -> scaleTransition
        NavigationAnimation.NONE -> noneTransition
    }
}

@Composable
fun <T : Any> AppNav3Host(
    modifier: Modifier = Modifier,
    start: T,
    entryProvider: (route: T) -> NavEntry<T>,
    backStack: SnapshotStateList<T> = remember { mutableStateListOf(start) },
//    onBack: (Int) -> Unit = { count -> repeat(count) { if (backStack.size > 1) backStack.removeAt(backStack.lastIndex) } },
    onBack: () -> Unit = {  if (backStack.size > 1) backStack.removeAt(backStack.lastIndex)  },
    transitionSpec: AnimatedContentTransitionScope<*>.() -> ContentTransform = {
        val animationType = Navigator3.consumeNavigationAnimation()
        getTransitionByType(animationType, isForward = true)()
    },
    popTransitionSpec: AnimatedContentTransitionScope<*>.() -> ContentTransform = {
        val animationType = Navigator3.consumePopAnimation()
        getTransitionByType(animationType, isForward = false)()
    },
) {
    // 绑定全局 Navigator3（可选，全局触发导航时使用）
    DisposableEffect(backStack) {
        @Suppress("UNCHECKED_CAST")
        Navigator3.bind(backStack as SnapshotStateList<Any>)
        onDispose { Navigator3.unbind() }
    }

    // 系统返回键/手势返回集成：当可返回时拦截并调用 onBack(1)
    BackHandler(enabled = backStack.size > 1) { onBack() }

    CompositionLocalProvider(LocalGlobalUiController provides GlobalUiBus) {
        GlobalUiLayer(modifier = modifier) {
            NavDisplay(
                backStack = backStack,
                onBack = onBack,
                entryProvider = entryProvider,
                transitionSpec = transitionSpec,
                popTransitionSpec = popTransitionSpec,
            )
        }
    }
}